#ifndef _THREAD_THREAD_H
#define _THREAD_THREAD_H
#include "stdint.h"

/*
 * 自定义通用函数类型，它将在很多线程函数中作为形参类型
 * C语言也支持函数式编程？
 */
typedef void thread_func(void*);

/*
 * 进程或线程的状态
 */
enum task_status {
    TASK_RUNNING,
    TASK_READY,
    TASK_BLOCKED,
    TASK_WAITING,
    TASK_HANGING,
    TASK_DIED
};

/*
 * 中断栈，用于中断发生时，保护程序（线程或进程）的上下文环境
 * 此栈在线程自己的内核中位置固定，所在页的最顶端
 */
struct intr_stack {
    uint32_t vec_no            //kernel.S宏VECTOR中push%1压入的中断号
    uint32_t edi;
    uint32_t esi;
    uint32_t ebp;
    uint32_t esp_dummy;

    uint32_t ebx;
    uint32_t edx;
    uint32_t ecx;
    uint32_t eax;
    uint32_t gs;
    uint32_t fs;
    uint32_t es;
    uint32_t ds;

    uint32_t err_code;
    void (*eip) (void);
    uint32_t cs;
    uint32_t eflags;
    void* esp;
    uint32_t ss;
};

/*
 * 线程栈
 * 线程自己的栈，用于存储线程中待执行的函数
 * 此结构在线程自己的栈中，位置不固定
 * 仅用在switch_to时保存线程环境
 * 实际位置取决于实际运行情况
 */
struct  thread_stack {
    uint32_t ebp;
    uint32_t ebx;
    uint32_t edi;
    uint32_t esi;

    /*
     * 线程第一次执行时，eip指向待调用的函数kernel_thread
     * 其他时候，eip是指向switch_to的返回地址
     */
    void (*eip) (thread_func* func, void* func_arg);

    //以下仅供第一次被调度上CPU时使用

    /*
     * 参数unused_ret只为占位置充数为返回地址
     */
    void (*unused_retadder);
    thread_func* function;         //由kernel_thread所调用的函数名
    void* func_arg;               //由kernel_thread所调用的函数所需的参数
};

/*
 * 进程或线程的pcb
 */
struct task_struct {
    uint32_t self_kstack;
    enum task_status status;
    uint8_t priority;
    char name[16];
    uint32_t stack_magic;
};

#endif